# To change this template, choose Tools | Templates
# and open the template in the editor.

$env = {:types=>{}}

def let(symbol, what)
  what.call(symbol)
end

class Enum
  def initialize(list_of_allowed_values)
    @allowed_values = list_of_allowed_values
  end

  def self.of(*args)
    Proc.new do | symbol |
      eval "class #{symbol} < #{self.to_s} \nend"
      klass = eval "#{symbol}"
      klass.init(args)
      Object.const_set(symbol.to_s, klass.class)
      $env[:types][symbol] = klass
    end
  end
  
  def self.init(args)
    @@authorized_values = args
    puts "Hello"
  end
end

let :Season, Enum.of(:Winter, :Spring)






require 'language'

# le monde est en deux dimensions

let :World2D, Entity.with(:x => Axis, :y => Axis)

let :Terre, Word2D.with(...)

Word2D_X_Metric.new(value, origin)
Word2D_Y_Metric.new(

lune = World2D.new
m.situer(lune,

terre = World2D.new
m.situer(terre,

# un emplacement est sur le monde et est situé sur les axes x et y

let :Location, Entity.on(World2D, upon(:x, :y))

let :Monster, Entity.with(:name => String, :respect => Axis).upon(Terre, :x, :y).upon(Monster, :respect)

Monster m1

Monster m2(:name ="t")

m1.position(m2)

m2.situer(m1, :respect => 3)
m2.situer(world, :x => 1, :y => 3)



position < -- Axis -- > upon

def position(arg)
  __position_#{arg.class.to_s}(arg)
end

def situer(arg, p)
  __situer_#{arg.class.to_s}(arg, p)
end


positions = Class => List of Metric

def self.upon(klass, *p)

  @situation_#{klass.to_s} = {}

  def __situer_#{klass.to_s}(target, p)
    metrics = {}
    p.each_pair do |key, value|
      metrics[key] = klass.metric(target, value)
    end
    @situation_#{klass.to_s}[target] = metrics
  end

  def __position_#{klass.to_s}(target)
    @situation_#{klass.to_s}[target]
  end

end


Metric met = m.position(word)

let :Position, Metric.from(Word2D, (:x, :y))


Location.locate(Entity)

# un repère hérite de emplacement et est caractérisé par une taille

let :Hideout, Location.with(:size => Integer)

# une divinité

let :Divinity, Entity.with(:name => String)

# un lieu de culte hérite de emplacement et est caractérisé par une divinité

let :WorshipPlace, Location.with(:divinity => Divinity)

# une ville hérite de emplacement et a un nom

# une ressource

let :Ressource, Entity.with(:name => String)

let :City, Location.with(:name => String)



